#https://www.bilibili.com/video/BV19541167cn?p=3&vd_source=c26a7d2aef5d2eddb9318602f0f58390
from abc import ABCMeta,abstractmethod
#抽象类，只定义了抽象方法（对外统一都叫pay),具体实现接口需要具体的类去实现
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        pass

#必须实现pay方法
class Alipei(Payment):
    def __init__(self,usehuabei=False):
        self.usehuabei=usehuabei

    def pay(self,money):
        if self.usehuabei:
            print("花呗支付%d元"%money)
        else:
            print("余额宝支付%d元"%money)

class WechatPay(Payment):
    def pay(self,money):
        print("微信支付%d元"%money)


class PaymentFactory:
    def create_payment(self,method):
        if method=='alipay':
            return Alipei()
        elif method=='wechat':
            return WechatPay()
        elif method=='huabei':
            return Alipei(usehuabei=True)
        else:
            return  TypeError("No such pay name %s"%method)
#工厂是创建一个个对象的，这些对象对外统一暴露的接口都非常简单，真正的复杂逻辑隐藏在工厂里
if __name__ == '__main__':
    pf=PaymentFactory()
    #外界调用的时候，只需要传一个支付方式和金额就行了，不管什么支付方式调用的都是pay方法
    #隐藏了对象创建实现细节，客户端不需要修改代码
    p=pf.create_payment('huabei')
    p.pay(100)